<!doctype html public "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
<html>
<head>
<title>
 Overview
</title>
<link rel ="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script>
function asd() {
	
		parent.document.title="jsoner.serializer.js Overview";
	
}
</script>
</head>
<body bgcolor="white" onload="asd();">

<!-- ========== START OF NAVBAR ========== -->
<a name="navbar_top"><!-- --></a>
<table border="0" width="100%" cellpadding="1" cellspacing="0">
<tr>
<td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1">
<a name="navbar_top_firstrow"><!-- --></a>
<table border="0" cellpadding="0" cellspacing="3">
  <tr align="center" valign="top">
  
  
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a>&nbsp;</td>
  <td bgcolor="#FFFFFF" class="NavBarCell1Rev">	&nbsp;<font class="NavBarFont1Rev"><b>File</b></font>&nbsp;</td>
  

  <td bgcolor="#FFFFFF" class="NavBarCell1"> 	<font class="NavBarFont1">Class</font>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a>&nbsp;</td>
  </tr>
</table>
</td>
<td bgcolor="#EEEEFF" align="right" valign="top">
<em>
<b></b></em>
</td>
</tr>

<tr>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</font></td>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
  <a href="index.html" target="_top"><b>FRAMES</b></a>  &nbsp;
&nbsp;<a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a>
&nbsp;&nbsp;
<script>
  <!--
  if(window==top) {
    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
  }
  //-->
</script>
<noscript>
<a href="allclasses-noframe.html" target=""><b>All Classes</b></a>
</noscript>
</font></td>
</tr>
</table>
<!-- =========== END OF NAVBAR =========== -->

<hr>
<center>
	
	   <h2>jsoner.serializer.js</h2>
	
</center>

	


<h4>Summary</h4>
<p>
	
		Main purpose of serializer create string representation of JavaSript object
 so well to be able to restore corresponding object instance by this string.
 It's allowed client JavaSript object to be transfered by network
 on server and conversely.

 Limitation:
 <ul>
  <li>object properties which are XML and DOM nodes are transient,
  in other words, there are excluded from traversing.
 </ul>

 Sulution:
 <ul>
 <li>Uses node lookup instead forward link on node.
 <li>Restore nodes by particular custom logic
 </ul>

 Serializer is easier, realy only two methods are used:
 <code>serialize(anObject)</code> is a method which is used to serialize object.
 <code>deserialize(aString)</code> is a method which is used to deserialize object.

 Serializer is flexible, it contains functionality allowed to register
 custom serializer/deserializer as a function which aware to create string
 representation for data with corresponding type or create instance
 of object by its string representation.

 Author: Alexey Luchkovsky
 E-mail: jsoner@soft-amis.com<BR/><BR/>
	
</p>

<hr>


    <table border="1" cellpadding="3" cellspacing="0" width="100%">
    <tr bgcolor="#CCCCFF" class="TableHeadingColor">
    <td colspan=2><font size="+2">
    
        <b>Class Summary</b>
    
    </font></td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="Serializer.html">Serializer</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="Walker.html">Walker</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    </table>
    <hr/> 


<!-- ========== METHOD SUMMARY =========== -->

<!-- ========== END METHOD SUMMARY =========== -->


        <pre class="sourceview"><span class="comment">/**
 * Copyright (c) 2007, Softamis, http://soft-amis.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Alexey Luchkovsky
 * E-mail: jsoner<span class="attrib">@soft</span>-amis.com
 *
 * Version: 1.24 alfa
 * Last modified: 06/06/2007
 */</span>

<span class="comment">/**
 * <span class="attrib">@fileoverview</span>
 *
 * Main purpose of serializer create string representation of JavaSript object
 * so well to be able to restore corresponding object instance by this string.
 * It's allowed client JavaSript object to be transfered by network
 * on server and conversely.
 *
 * Limitation:
 * &lt;ul&gt;
 *  &lt;li&gt;object properties which are XML and DOM nodes are transient,
 *  in other words, there are excluded from traversing.
 * &lt;/ul&gt;
 *
 * Sulution:
 * &lt;ul&gt;
 * &lt;li&gt;Uses node lookup instead forward link on node.
 * &lt;li&gt;Restore nodes by particular custom logic
 * &lt;/ul&gt;
 *
 * Serializer is easier, realy only two methods are used:
 * &lt;code&gt;serialize(anObject)&lt;/code&gt; is a method which is used to serialize object.
 * &lt;code&gt;deserialize(aString)&lt;/code&gt; is a method which is used to deserialize object.
 *
 * Serializer is flexible, it contains functionality allowed to register
 * custom serializer/deserializer as a function which aware to create string
 * representation for data with corresponding type or create instance
 * of object by its string representation.
 *
 * Author: Alexey Luchkovsky
 * E-mail: jsoner<span class="attrib">@soft</span>-amis.com
 */</span>

var SERIALIZER =
{
  version: 1.24
};

<span class="comment">/**
 * Defines set of JavaScript reserved words.
 * http://www.quackit.com/javascript/javascript_reserved_words.cfm
 */</span>
SERIALIZER.RESERVED_WORDS = new KeySet( <span class="literal">"abstract"</span>, <span class="literal">"as"</span>, <span class="literal">"boolean"</span>, <span class="literal">"break"</span>, <span class="literal">"byte"</span>, <span class="literal">"case"</span>, <span class="literal">"catch"</span>, <span class="literal">"char"</span>,
			                                  <span class="literal">"class"</span>, <span class="literal">"continue"</span>, <span class="literal">"const"</span>, <span class="literal">"debugger"</span>, <span class="literal">"default"</span>, <span class="literal">"delete"</span>, <span class="literal">"do"</span>,
																 			  <span class="literal">"double"</span>, <span class="literal">"else"</span>, <span class="literal">"enum"</span>, <span class="literal">"export"</span>, <span class="literal">"extends"</span>, <span class="literal">"false"</span>, <span class="literal">"final"</span>, <span class="literal">"finally"</span>,
				                                <span class="literal">"float"</span>, <span class="literal">"for"</span>, <span class="literal">"function"</span>, <span class="literal">"goto"</span>, <span class="literal">"if"</span>, <span class="literal">"implements"</span>, <span class="literal">"import"</span>, <span class="literal">"in"</span>,
				                                <span class="literal">"instanceof"</span>, <span class="literal">"int"</span>, <span class="literal">"interface"</span>, <span class="literal">"is"</span>, <span class="literal">"long"</span>, <span class="literal">"let"</span>, <span class="literal">"namespace"</span>, <span class="literal">"native"</span>,
				                                <span class="literal">"new"</span>, <span class="literal">"null"</span>, <span class="literal">"package"</span>, <span class="literal">"private"</span>, <span class="literal">"prototype"</span>, <span class="literal">"protected"</span>, <span class="literal">"public"</span>, <span class="literal">"return"</span>,
			                                  <span class="literal">"short"</span>, <span class="literal">"static"</span>, <span class="literal">"super"</span>, <span class="literal">"switch"</span>, <span class="literal">"synchronized"</span>, <span class="literal">"this"</span>, <span class="literal">"throw"</span>, <span class="literal">"throws"</span>,
																			  <span class="literal">"transient"</span>, <span class="literal">"true"</span>, <span class="literal">"try"</span>, <span class="literal">"typeof"</span>, <span class="literal">"use"</span>, <span class="literal">"var"</span>, <span class="literal">"void"</span>, <span class="literal">"volatile"</span>,
																			  <span class="literal">"while"</span>, <span class="literal">"with"</span>);

<span class="comment">/**
 * Defines a map, which used to cache default object instances.
 * The cache structure is: {String}object type - {Object}object instance.
 */</span>
SERIALIZER.fDefaults = new HashMap();

<span class="comment">/**
 * Creates a Walker.
 * Walker extends Jsoner and used to traverse JavaScript objects.
 * <span class="attrib">@constructor</span>
 */</span>
<span class="reserved">function</span> Walker()
{
	var self = JSINER.extend(<span class="reserved">this</span>, Jsoner);
	self.isWalkNode = <span class="reserved">function</span>(aName, aValue)
	{
		<span class="reserved">return</span> COMMONS.isObject(aValue) &amp;&amp; isNaN(aValue.nodeType);
	};
	<span class="reserved">return</span> self;
}

<span class="comment">/**
 * Redefines logger.
 */</span>
Walker.<span class="reserved">prototype</span>.fLogger = new Logger(<span class="literal">"Serializer.Walker"</span>);

<span class="comment">/**
 * Converts property name to attribute name.
 * Corresponding to JSON specification property name always should be wrapped in brackets,
 * to serialize JavaScript object it not needs always.
 *
 * <span class="attrib">@param</span> {String} The object property name.
 * <span class="attrib">@return</span> {String} The corresponding to property attribute name.
 */</span>
Walker.<span class="reserved">prototype</span>.getAttrName = <span class="reserved">function</span>(aName)
{
	var result = String(aName);
	<span class="reserved">if</span> ( SERIALIZER.RESERVED_WORDS.isContains(result) || result.indexOf(<span class="literal">' '</span>) &gt;= 0 || result.indexOf(<span class="literal">'.'</span>) &gt;=0 )
	{
		result = <span class="literal">'"'</span> + result + <span class="literal">'"'</span>;
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Indicates that the object property should be ignored.
 * Overrides Jsoner method to skip nodes and include object methods to walker.
 * <span class="attrib">@return</span> {Boolean} If so it returns true, otherwise it returns false.
 *
 * <span class="attrib">@param</span> {String} The property name.
 * <span class="attrib">@param</span> The property value.
 * <span class="attrib">@param</span> The parent object.
 */</span>
Walker.<span class="reserved">prototype</span>.isMute = <span class="reserved">function</span>(aName, aValue, aParent)
{
	var result = aName === Jsoner.MAGIC_HASH_CODE || !aParent.hasOwnProperty(aName) ||
	             (COMMONS.isObject(aValue) &amp;&amp; !isNaN(aValue.nodeType));
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Returns default instance of the object.
 * Checks if object instance already was created,
 * if it is not true, creates new instance by object
 * constructor and them puts the instance in cache.
 *
 * <span class="attrib">@return</span> Returns default instance of the object.
 * <span class="attrib">@param</span>  The object.
 */</span>
Walker.<span class="reserved">prototype</span>.getDefaultInstance = <span class="reserved">function</span>(anObject)
{
	var type = JSINER.getType(anObject);
	var result = SERIALIZER.fDefaults.get(type);
	<span class="reserved">if</span> (COMMONS.isUndefined(result))
	{
		result = anObject;
		<span class="reserved">if</span> (COMMONS.isObject(anObject))
		{
			try
			{
				var cons = JSINER.getConstructor(anObject);
				result = new cons();

				SERIALIZER.fDefaults.put(type, result);
			}
			catch(ex)
			{
				<span class="reserved">this</span>.fLogger.warning(<span class="literal">"getDefaultInstance, unable to create new instance:"</span> + type, ex);
			}
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Indicates that the object property already presents
 * by defaults in object instance and property value is equals with default value.
 * <span class="attrib">@return</span> {Boolean} If so it returns true, otherwise it returns false.
 *
 * <span class="attrib">@param</span> The default instance of the object.
 * <span class="attrib">@param</span> {String} The path to obtain object property.
 * <span class="attrib">@param</span> The property value.
 */</span>
Walker.<span class="reserved">prototype</span>.isDefaultProperty = <span class="reserved">function</span>(aDefault, aName, aValue)
{
	var result = false;
	<span class="reserved">if</span> ( COMMONS.isDefined(aDefault) )
	{
		try
		{
			var value = <span class="reserved">this</span>.getValue(aDefault, aName);
			result = <span class="reserved">this</span>.isEquals(aValue, value);
		}
		catch(ex)
		{
			<span class="reserved">this</span>.fLogger.warning(<span class="literal">"isDefaultProperty, unable to get property:"</span> + aName, ex);
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Creates default instance of an array;
 */</span>
Walker.<span class="reserved">prototype</span>.array = [];

<span class="comment">/**
 * Indicates that the argument is a pure array.
 * <span class="attrib">@return</span> {Boolean} If so it returns true, otherwise it returns false.
 *
 * <span class="attrib">@param</span> The value to be checked.
 */</span>
Walker.<span class="reserved">prototype</span>.isPureArray = <span class="reserved">function</span>(anObject)
{
  var result = COMMONS.isArray(anObject);
	<span class="reserved">if</span> ( result )
	{
		var value;
		<span class="reserved">for</span> (var name in anObject)
		{
			<span class="reserved">if</span> ( name != Jsoner.MAGIC_HASH_CODE )
			{
				value = anObject[name];
				<span class="reserved">if</span> ( isNaN(Number(name)) &amp;&amp; !<span class="reserved">this</span>.isDefaultProperty(<span class="reserved">this</span>.array, name, value) )
				{
					result = false;
					break;
				}
			}
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
  * Collects the object attributes to array as pair name-value
  * &lt;samp&gt;{name:name, value:value}&lt;/samp&gt;.
  * Overrides Jsoner method to skip default object properties.
  * <span class="attrib">@return</span> {Array} An array of attributes.
  *
  * <span class="attrib">@param</span> {Array} The path as array to walked node.
  * <span class="attrib">@param</span> The node value.
  * <span class="attrib">@param</span> The top level object.
  */</span>
Walker.<span class="reserved">prototype</span>.collectAttributes = <span class="reserved">function</span>(aPath, aValue, anObject)
{
	var result = [];
	var value;
	var property;

	<span class="reserved">if</span> ( COMMONS.isDefined(aValue) )
	{
		var def = <span class="reserved">this</span>.getDefaultInstance(anObject);
		var path = aPath.join(<span class="literal">'.'</span>);
		<span class="reserved">for</span> (var name in aValue)
		{
			try
			{
				value = aValue[name];
				<span class="reserved">if</span> ( !<span class="reserved">this</span>.isMute(name, value, aValue) &amp;&amp; <span class="reserved">this</span>.isAttribute(name, value) )
				{
					property = path.length &gt; 0 ? path + <span class="literal">"."</span> + name : name;
					<span class="reserved">if</span> ( !<span class="reserved">this</span>.isDefaultProperty(def, property, value) )
					{
						result.push({name:name, value:value});
					}
				}
			}
			catch(ex)
			{
				<span class="reserved">this</span>.fLogger.error(<span class="literal">"collectAttributes, unable to collect attribute:"</span> + name, ex);
			}
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
  * Collects the object children to array as pair name-value
  * &lt;samp&gt;{name:name, value:value}&lt;/samp&gt;.
  * Overrides Jsoner method to skip default object properties.
  * <span class="attrib">@return</span> {Array} An array of node children.
  *
  * <span class="attrib">@param</span> {Array} The path as array to walked node.
  * <span class="attrib">@param</span> The node value.
  * <span class="attrib">@param</span> The top level object.
  *
  * <span class="attrib">@see</span> #isDefaultProperty.
  */</span>
Walker.<span class="reserved">prototype</span>.collectChildren = <span class="reserved">function</span>(aPath, aValue, anObject)
{
	var value;
	var property;
	var result = [];
	<span class="reserved">if</span> ( !<span class="reserved">this</span>.isPureArray(aValue) )
	{
		var def = <span class="reserved">this</span>.getDefaultInstance(anObject);
		var path = aPath.join(<span class="literal">'.'</span>);
		<span class="reserved">for</span> (var name in aValue)
		{
			try
			{
				value = aValue[name];
				<span class="reserved">if</span> ( !<span class="reserved">this</span>.isMute(name, value, aValue) &amp;&amp; !<span class="reserved">this</span>.isAttribute(name, value) )
				{
					property = path.length &gt; 0 ? path + <span class="literal">"."</span> + name : name;
					<span class="reserved">if</span> ( !<span class="reserved">this</span>.isDefaultProperty(def, property, value) )
					{
						result.push( {name:name, value:value} );
					}
				}
			}
			catch(ex)
			{
				<span class="reserved">this</span>.fLogger.warning( <span class="literal">"collectChildren, unable to collect child:"</span> + name, ex);
			}
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/********************************************/</span>

<span class="comment">/**
 * Creates JavaScript object serializer.
 * <span class="attrib">@constructor</span>
 * Main purpose of serializer create string representation of JavaSript object
 * so well to be able to restore corresponding object instance by this string.
 * It's allowed client JavaSript object to be transfered by network
 * on server and conversely.
 *
 * Limitation:
 * &lt;ul&gt;
 *  &lt;li&gt;object properties which are XML and DOM nodes are transient,
 *  in other words, there are excluded from traversing.
 * &lt;/ul&gt;
 *
 * Sulution:
 * &lt;ul&gt;
 * &lt;li&gt;Uses node lookup instead forward link on node.
 * &lt;li&gt;Restore nodes by particular custom logic
 * &lt;/ul&gt;
 *
 * Serializer is easier, realy only two methods are used:
 * &lt;code&gt;serialize(anObject)&lt;/code&gt; is a method which is used to serialize object.
 * &lt;code&gt;deserialize(aString)&lt;/code&gt; is a method which is used to deserialize object.
 *
 * Serializer is flexible, it contains functionality allowed to register
 * custom serializer/deserializer as a function which aware to create string
 * representation for data with corresponding type or create instance
 * of object by its string representation.
 */</span>
<span class="reserved">function</span> Serializer(aPettyPrint)
{
	<span class="reserved">function</span> ValueWalker()
	{
		<span class="reserved">return</span> JSINER.extend(<span class="reserved">this</span>, Walker);
	}

	ValueWalker.<span class="reserved">prototype</span>.getDefaultInstance = <span class="reserved">function</span>(anObject)
	{
		var def = ValueWalker.superClass.getDefaultInstance.call(<span class="reserved">this</span>, anObject.value);
		<span class="reserved">return</span> { value:def };
	};

  <span class="reserved">this</span>.fSerializers   = new HashMap();
	<span class="reserved">this</span>.fDeserializers = new HashMap();

	<span class="reserved">this</span>.fPettyPrint = aPettyPrint;

	<span class="reserved">this</span>.fWalker = new ValueWalker();
	<span class="reserved">this</span>.fWalker.isWalkArray = <span class="reserved">function</span>(aName, aValue)
	{
		<span class="reserved">return</span> false;
	};

	<span class="reserved">this</span>.fCrossLinker = new ValueWalker();
  <span class="reserved">this</span>.initProcessors();
}

Serializer.FIELD_TYPE   = <span class="literal">"type"</span>;
Serializer.FIELD_STREAM = <span class="literal">"data"</span>;

Serializer.DECODE_TABLE   = {<span class="literal">'\b'</span>: <span class="literal">'\\b'</span>,	<span class="literal">'\t'</span>: <span class="literal">'\\t'</span>, <span class="literal">'\n'</span>: <span class="literal">'\\n'</span>, <span class="literal">'\f'</span>: <span class="literal">'\\f'</span>, <span class="literal">'\r'</span>: <span class="literal">'\\r'</span>, <span class="literal">'"'</span> : <span class="literal">'\\"'</span>,	<span class="literal">'\\'</span>: <span class="literal">'\\\\'</span>};
Serializer.REGEXP_TEST    = /[<span class="literal">"\\\x00-\x1f]/;
Serializer.REGEXP_REPLACE = /([\x00-\x1f\\"</span>])/g;

<span class="comment">/**
 * Predefined object method name to externalize object.
 */</span>
Serializer.SERIALIZE_METHOD  = <span class="literal">"toJSONString"</span>;

<span class="comment">/**
 * Predefined object method name to restore externalized object.
 */</span>
Serializer.DESERIALIZE_METHOD = <span class="literal">"stringToJSON"</span>;

<span class="comment">/**
 * Defines Serializer logger.
 */</span>
Serializer.<span class="reserved">prototype</span>.fLogger = new Logger(<span class="literal">"Serializer"</span>);

<span class="comment">/**
 * Registers serializer.
 * A serializer is a function which aware to create
 * string representation for an object with corresponding type.
 *
 * <span class="attrib">@param</span> {String} The object type.
 * <span class="attrib">@param</span> {Function} The custom serializer.
 */</span>
Serializer.<span class="reserved">prototype</span>.registerSerializer = <span class="reserved">function</span>(aType, aSerializer)
{
	<span class="reserved">if</span> ( COMMONS.isFunction(aSerializer) )
	{
		<span class="reserved">this</span>.fSerializers.put(aType, aSerializer);
	}
	<span class="reserved">else</span>
	{
		<span class="reserved">this</span>.fLogger.warning( <span class="literal">"registerSerializer, illegal argument type:"</span> + aSerializer);
	}
};

<span class="comment">/**
 * Registers deserializer.
 * A deserializer is a function which aware to create
 * instance of the object by its string representation.
 *
 * <span class="attrib">@param</span> {String} The object type.
 * <span class="attrib">@param</span> {Function} The custom deserializer.
 */</span>
Serializer.<span class="reserved">prototype</span>.registerDeserializer = <span class="reserved">function</span>(aType, aDeserializer)
{
	<span class="reserved">if</span> ( COMMONS.isFunction(aDeserializer) )
	{
		<span class="reserved">this</span>.fDeserializers.put(aType, aDeserializer);
	}
	<span class="reserved">else</span>
	{
		<span class="reserved">this</span>.fLogger.warning( <span class="literal">"registerSerializer, illegal argument type:"</span> + aDeserializer);
	}
};

<span class="comment">/**
 * Registers predefined serializers and deserializers.
 *
 * <span class="attrib">@see</span> #registerSerializer
 * <span class="attrib">@see</span> #registerDeserializer
 */</span>
Serializer.<span class="reserved">prototype</span>.initProcessors = <span class="reserved">function</span>()
{
	<span class="reserved">this</span>.registerSerializer(<span class="literal">"object"</span>, <span class="reserved">this</span>.serializeObject);
	<span class="reserved">this</span>.registerDeserializer(<span class="literal">"object"</span>, <span class="reserved">this</span>.deserializeObject );
	<span class="reserved">this</span>.registerSerializer(<span class="literal">"string"</span>, <span class="reserved">this</span>.serializeString );
	<span class="reserved">this</span>.registerSerializer(<span class="literal">"function"</span>, <span class="reserved">this</span>.serializeFunction );
	<span class="reserved">this</span>.registerSerializer(<span class="literal">"Date"</span>, <span class="reserved">this</span>.serializeDate);
	<span class="reserved">this</span>.registerDeserializer(<span class="literal">"Date"</span>, <span class="reserved">this</span>.deserializeDate);
	<span class="reserved">this</span>.registerSerializer(<span class="literal">"RegExp"</span>, <span class="reserved">this</span>.serializeRegexp);
};

<span class="comment">/**
 * Obtains object serializer.
 * Checks predefined object method to externalize object
 * &lt;code&gt;object.toJSONString()&lt;/code&gt;,
 * if it can't be resolved uses map to get serializer
 * by object type. If noting is found, returns default serializer.
 *
 * <span class="attrib">@return</span> {Function} Returns corresponding serializer.
 *
 * <span class="attrib">@param</span> The object used to obtain serializer.
 */</span>
Serializer.<span class="reserved">prototype</span>.getSerializer = <span class="reserved">function</span>(anObject)
{
	<span class="reserved">function</span> defaultSerializer(anObject)
	{
		<span class="reserved">return</span> String(anObject);
	}

	var result = null;
	<span class="reserved">if</span> ( COMMONS.isDefined(anObject) )
	{
		result = anObject[Serializer.SERIALIZE_METHOD];
		<span class="reserved">if</span> ( !COMMONS.isFunction(result) )
		{
			result = <span class="reserved">this</span>.fSerializers.get( JSINER.getType(anObject) );
			<span class="reserved">if</span> ( !COMMONS.isFunction(result) )
			{
				result = <span class="reserved">this</span>.fSerializers.get( typeof(anObject) );
			}
		}
	}
	<span class="reserved">if</span> (!COMMONS.isFunction(result))
	{
		result = defaultSerializer;
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Obtains object deserializer.
 * Checks predefined object method to restore object
 * from externalize form: "stringToJSON",
 * if it can't be resolved, gets deserializer by object type.
 * If noting is found returns default deserializer.
 *
 * <span class="attrib">@return</span> {Function} Returns corresponding deserializer.
 * <span class="attrib">@param</span> The object used to obtain deserializer.
 */</span>
Serializer.<span class="reserved">prototype</span>.getDeserializer = <span class="reserved">function</span>(anObject)
{
	var result = COMMONS.isDefined(anObject) ? anObject[Serializer.DESERIALIZE_METHOD] : null;
	<span class="reserved">if</span> ( !COMMONS.isFunction(result) &amp;&amp; COMMONS.isDefined(anObject) )
	{
		var type = anObject[Serializer.FIELD_TYPE];
		<span class="reserved">if</span> ( COMMONS.isDefined(type) )
		{
			result = <span class="reserved">this</span>.fDeserializers.get(type);
		}
	}
	<span class="reserved">if</span> (!COMMONS.isFunction(result))
	{
		result = <span class="reserved">this</span>.fDeserializers.get(typeof(anObject));
		<span class="reserved">if</span> (!COMMONS.isFunction(result))
		{
			result = COMMONS.proxy;
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Date serializer.
 * <span class="attrib">@return</span> {String} Returns string representation of the Date.
 * <span class="attrib">@param</span> {Date} The object used to create string representation of Date.
 *
 * <span class="attrib">@see</span> #deserializeDate
 */</span>
Serializer.<span class="reserved">prototype</span>.serializeDate = <span class="reserved">function</span>(aDate)
{
	var time = aDate.getTime();
	aDate.time = aDate.getTime();

	var result = <span class="reserved">this</span>.serializeObject(aDate);

  aDate.time = undefined;
	delete aDate[<span class="literal">"time"</span>];
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Date deserializer.
 * <span class="attrib">@param</span> {Object} The initial object that represents the Date.
 * <span class="attrib">@return</span> {Date} Returns new Date by its initial representation.
 *
 * <span class="attrib">@see</span> #serializeDate
 */</span>
Serializer.<span class="reserved">prototype</span>.deserializeDate = <span class="reserved">function</span>(aString)
{
  var result = <span class="reserved">this</span>.deserializeObject(aString);
	<span class="reserved">if</span> ( COMMONS.isDefined(result.time) )
	{
		result.setTime(result.time);
		result.time = undefined;
		delete result[<span class="literal">"time"</span>];
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * RegExp serializer.
 *
 * <span class="attrib">@return</span> {String} Returns string representation of the RegExp.
 * <span class="attrib">@param</span> {RegExp} The object used to create string representation.
 */</span>
Serializer.<span class="reserved">prototype</span>.serializeRegexp = <span class="reserved">function</span>(aRegExp)
{
  <span class="reserved">return</span> aRegExp.toString();
};

<span class="comment">/**
 * Function serializer.
 *
 * <span class="attrib">@return</span> {String} Returns string representation of the Function.
 * <span class="attrib">@param</span> {Function} The object used to create string representation.
 */</span>
Serializer.<span class="reserved">prototype</span>.serializeFunction = <span class="reserved">function</span>(aFunc)
{
  var result = aFunc.toString();
	var ind1 = result.indexOf(<span class="literal">' '</span>)+ 1;
	var ind2 = result.indexOf(<span class="literal">'('</span>);
	<span class="reserved">if</span> ( ind1 &lt; ind2)
	{
	  result = result.substring(ind1, ind2);
  }
  <span class="reserved">else</span>
  {
    <span class="reserved">this</span>.fLogger.warning(<span class="literal">"serializeFunction, anonymous function: "</span> + result);
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * String serializer.
 * Code from http://www.json.org/json.js (2007-03-01) was used.
 *
 * <span class="attrib">@return</span> {String} Returns string representation of the String.
 * <span class="attrib">@param</span> {String} The object used to create string representation.
 */</span>
Serializer.<span class="reserved">prototype</span>.serializeString = <span class="reserved">function</span>(aString)
{
	<span class="reserved">if</span> ( Serializer.REGEXP_TEST.test(aString) )
	{
		aString = aString.replace(Serializer.REGEXP_REPLACE, <span class="reserved">function</span>(a, b)
		{
			var c = Serializer.DECODE_TABLE[b];
			<span class="reserved">if</span> ( COMMONS.isDefined(c) )
			{
				<span class="reserved">return</span> c;
			}
			c = b.charCodeAt();
			<span class="reserved">return</span> <span class="literal">'\\u00'</span> + Math.floor(c/16).toString(16) + (c%16).toString(16);
		});
	}
	<span class="reserved">return</span> <span class="literal">'"'</span> + aString + <span class="literal">'"'</span>;
};

<span class="comment">/**
 * Object serializer.
 *
 * <span class="attrib">@return</span> {String} Returns string representation of the object.
 * <span class="attrib">@param</span> {Object} The object used to create string representation.
 *
 * <span class="attrib">@see</span> #deserializeObject
 */</span>
Serializer.<span class="reserved">prototype</span>.serializeObject = <span class="reserved">function</span>(anObject)
{
	var result= <span class="literal">""</span>;
  var stack = [];
	var serializer = <span class="reserved">this</span>;
	var pettyPrint = <span class="reserved">this</span>.fPettyPrint;

	<span class="reserved">this</span>.fWalker.jsonTreeWalker( { value:anObject }, <span class="reserved">function</span>(aPath, aValue, anAttributes, aType)
	{
	  var value;
		var func;
		var b = false;

	  <span class="reserved">if</span> ( aType === Jsoner.JSON_NODE_START || aType === Jsoner.JSON_NODE_LEAF )
	  {
		  <span class="reserved">if</span> (aPath.length &gt; 1 )
		  {
			  <span class="reserved">if</span> (result.charAt(result.length - 1) !== <span class="literal">'{'</span> )
			  {
				  result += pettyPrint ? <span class="literal">",\n"</span> : <span class="literal">","</span>;
			  }
        result += <span class="reserved">this</span>.getAttrName( <span class="reserved">this</span>.getLastProperty(aPath) ) + <span class="literal">":"</span>;
		  }

		  <span class="reserved">if</span> ( <span class="reserved">this</span>.isPureArray(aValue) )
		  {
			  result += <span class="literal">"["</span>;
			  <span class="reserved">for</span> (var i = 0; i &lt; aValue.length; i++)
			  {
				  func = serializer.getSerializer(aValue[i]);
				  <span class="reserved">if</span> (COMMONS.isFunction(func))
				  {
						<span class="reserved">if</span> (b)
						{
							result += <span class="literal">","</span>;
						}
					  result += func.call(serializer, aValue[i]);
					  b = true;
				  }
			  }
			  stack.push(<span class="literal">"]"</span>);
		  }
		  <span class="reserved">else</span>
			{
				var type = JSINER.getType(aValue);
				<span class="reserved">if</span> (type === <span class="literal">"Object"</span>)
				{
					result += <span class="literal">"{"</span>;
          stack.push(<span class="literal">"}"</span>);
				}
				<span class="reserved">else</span>
				{
					result += <span class="literal">'{"'</span> + Serializer.FIELD_TYPE + <span class="literal">'":"'</span> + type + <span class="literal">'",'</span>;
					result += <span class="literal">'"'</span> + Serializer.FIELD_STREAM + <span class="literal">'":'</span> + (pettyPrint ? <span class="literal">"\n{"</span> : <span class="literal">' {'</span>);
					stack.push( pettyPrint ? <span class="literal">"}\n}"</span>:  <span class="literal">"}}"</span>);
				}

				<span class="reserved">for</span> (var i = 0; i &lt; anAttributes.length; i++)
				{
					value = anAttributes[i].value;

					func = serializer.getSerializer(value);
					<span class="reserved">if</span> (COMMONS.isFunction(func))
					{
						value = func.call(serializer, value);
						<span class="reserved">if</span> (b)
						{
							result += pettyPrint ? <span class="literal">",\n"</span> : <span class="literal">","</span>;
						}
						result += <span class="reserved">this</span>.getAttrName(anAttributes[i].name) + <span class="literal">':'</span> + value;
						b = true;
					}
				}
			}
		}

	  <span class="reserved">if</span> ( aType === Jsoner.JSON_NODE_END || aType === Jsoner.JSON_NODE_LEAF )
	  {
		  result += stack.pop();
	  }
		<span class="reserved">return</span> true;
	});

	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Object deserializer.
 * <span class="attrib">@param</span> {Object} The initial object.
 * <span class="attrib">@return</span> {Date} Returns new object instance by its initial representation.
 *
 * <span class="attrib">@see</span> #serializeObject
 */</span>
Serializer.<span class="reserved">prototype</span>.deserializeObject = <span class="reserved">function</span>(anObject)
{
	var result = anObject;
	var value;
	var func;
	<span class="reserved">if</span> ( COMMONS.isObject(anObject) )
	{
		var type = anObject[ Serializer.FIELD_TYPE ];
		<span class="reserved">if</span> ( COMMONS.isString(type) )
		{
			try
			{
				var cons = JSINER.getConstructor(type);
				result =  new cons();

				var data = anObject[ Serializer.FIELD_STREAM ];
				<span class="reserved">if</span> ( COMMONS.isObject(data) )
				{
					<span class="reserved">for</span> (var name in data)
					{
					  <span class="reserved">if</span> ( data.hasOwnProperty(name) )
					  {
							value = anObject.data[name];
							func = <span class="reserved">this</span>.getDeserializer(value);
							<span class="reserved">if</span> (COMMONS.isFunction(func))
							{
								result[name] = func.call(<span class="reserved">this</span>, value);
							}
						}
					}
				}
			}
			catch(ex)
			{
				<span class="reserved">this</span>.fLogger.error(<span class="literal">"deSerialize error "</span> + type, ex);
			}
		}
		<span class="reserved">else</span>
		{
			<span class="reserved">for</span> (var name in anObject)
			{
				<span class="reserved">if</span> ( anObject.hasOwnProperty(name) )
				{
					value = anObject[name];
					func = <span class="reserved">this</span>.getDeserializer(value);
					<span class="reserved">if</span> (COMMONS.isFunction(func))
					{
						result[name] = func.call(<span class="reserved">this</span>, value);
					}
				}
			}
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Base serialize method.
 * Selects corresponding serializer by given object and
 * use them creates string representation of the object.
 *
 * <span class="attrib">@return</span> {String} Returns string representation of the object.
 * <span class="attrib">@param</span> {Object} The object used to create string representation.
 */</span>
Serializer.<span class="reserved">prototype</span>.serialize = <span class="reserved">function</span>(anObject)
{
	var result = <span class="literal">"undefined"</span>;
  var func = <span class="reserved">this</span>.getSerializer(anObject);

	<span class="reserved">if</span> ( COMMONS.isDefined(func) )
	{
		try
		{
			result = func.call(<span class="reserved">this</span>, anObject);
			
			var pettyPrint = <span class="reserved">this</span>.fPettyPrint;
			<span class="reserved">this</span>.fCrossLinker.jsonPathEvaluator( {value:anObject}, <span class="reserved">function</span>(aPath, aValue, aType)
			{
				<span class="reserved">if</span> ( aType === Jsoner.JSON_NODE_CROSS_LINKED )
				{
					result += pettyPrint ? <span class="literal">";\n"</span> : <span class="literal">";"</span>;
					var value = aValue.substring(6 + Jsoner.CROSS_LINK_PREFIX.length); <span class="comment">// "value." length = 6</span>
					result += Jsoner.CROSS_LINK_PREFIX + <span class="literal">"."</span>+ aPath.substring(6) + <span class="literal">"="</span> + (value.length &gt; 0 ? + <span class="literal">"result."</span> + value : <span class="literal">"result"</span>);
				}
				<span class="reserved">return</span> true;
			});
		}
		catch(ex)
		{
			<span class="reserved">this</span>.fLogger.error(<span class="literal">"serialize error"</span>, ex);
		}
		result += <span class="literal">";"</span>
	}
	<span class="reserved">else</span>
	{
	  <span class="reserved">this</span>.fLogger.error(<span class="literal">"serialize, corresponding serializer not found:"</span> + anObject );
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Base deserialize method.
 * Selects corresponding deserializer by string representation
 * of the object and creates new object instance.
 *
 * <span class="attrib">@param</span> {String} The string representation of the Object.
 * <span class="attrib">@return</span> {Date} Returns new object instance by its string representation.
 *
 */</span>
Serializer.<span class="reserved">prototype</span>.deserialize = <span class="reserved">function</span>(aString)
{
	var result = undefined;
	<span class="reserved">if</span> ( COMMONS.isString(aString) )
	{
		var object = aString;
		var crossLink = null;

		var index = aString.indexOf(Jsoner.CROSS_LINK_PREFIX);
    <span class="reserved">if</span> (index &gt; 0)
    {
	    object = aString.substring(0, index);
	    crossLink = aString.substring(index).replace(new RegExp(Jsoner.CROSS_LINK_PREFIX, <span class="literal">"g"</span>), <span class="literal">"result"</span>);
	  }
		try
		{
			var $json = undefined;
			eval( <span class="literal">"$json ="</span> + object);
			<span class="reserved">if</span> ( $json !== undefined )
			{
				var func = <span class="reserved">this</span>.getDeserializer($json);
				<span class="reserved">if</span> ( COMMONS.isDefined(func) )
				{
					result = func.call(<span class="reserved">this</span>, $json);
				}
			}

			<span class="reserved">if</span> ( crossLink !== null )
			{
				try
				{
					eval(crossLink);
				}
				catch(ex)
				{
					<span class="reserved">this</span>.fLogger.error(<span class="literal">"deSerialize, unable to deserialize cross links:"</span> + crossLink, ex)
				}
			}
		}
		catch(ex)
		{
			<span class="reserved">this</span>.fLogger.error(<span class="literal">"deSerialize error"</span>, ex)
		}
	}
	<span class="reserved">else</span>
	{
		<span class="reserved">this</span>.fLogger.error(<span class="literal">"deSerialize error, illegal argument type:"</span> + aString )
	}
	<span class="reserved">return</span> result;
};</pre>
	<hr>



<!-- ========== START OF NAVBAR ========== -->
<a name="navbar_top"><!-- --></a>
<table border="0" width="100%" cellpadding="1" cellspacing="0">
<tr>
<td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1">
<a name="navbar_top_firstrow"><!-- --></a>
<table border="0" cellpadding="0" cellspacing="3">
  <tr align="center" valign="top">
  
  
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a>&nbsp;</td>
  <td bgcolor="#FFFFFF" class="NavBarCell1Rev">	&nbsp;<font class="NavBarFont1Rev"><b>File</b></font>&nbsp;</td>
  

  <td bgcolor="#FFFFFF" class="NavBarCell1"> <font class="NavBarFont1">Class</font>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a>&nbsp;</td>
  </tr>
</table>
</td>
<td bgcolor="#EEEEFF" align="right" valign="top"><em>
<b></b></em>
</td>
</tr>

<tr>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</font></td>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
  <a href="index.html" target="_top"><b>FRAMES</b></a>  &nbsp;
&nbsp;<a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a>
&nbsp;&nbsp;
<script>
  <!--
  if(window==top) {
    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
  }
  //-->
</script>
<noscript>
<a href="allclasses-noframe.html" target=""><b>All Classes</b></a>
</noscript>
</font></td>
</tr>
</table>
<!-- =========== END OF NAVBAR =========== -->

<hr>
<font size="-1">
<p class='footer'>Copyright (c) 2007, <a href='http://soft-amis.com'>SoftAMIS<a></p>
</font>
<div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Tue Jun  5 15:32:30 2007</div>
</body>
</html>
